# views.py - 修复版
import random
import string
from datetime import timedelta
from django.conf import settings
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.core.mail import send_mail
from django.core.paginator import Paginator
from django.db.models import Count, Q, Sum
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from user.models import User, PasswordResetCode
from django.contrib.auth import login as auth_login, logout as auth_logout
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods, require_POST
from meet.models import Activity, ActivityParticipation, UserRelationship, ActivityCategory, ActivityReview, PointsRule, \
    PointsHistory, DailySignIn, PointsProduct, PointsExchange
from user.models import User, UserProfile
import base64
from django.core.files.base import ContentFile

from .consumers import logger
from .models import PrivateMessage,UserFollow
from .models import UserBlacklist, ChatGroup, GroupMembership, GroupMessage, MessageReadStatus
import json

from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from .models import User, UserFollow
from .utils.qq_oauth import OAuthQQ


def login(request):
    """用户登录视图 - 使用邮箱登录"""
    print(f"请求方法: {request.method}")

    # 处理注册请求
    if 'reg_username' in request.POST:
        username = request.POST.get('reg_username')
        email = request.POST.get('reg_email')
        password = request.POST.get('reg_password')
        password2 = request.POST.get('reg_confirm_password')

        # 用户名长度验证 (2-20字符)
        if len(username) < 2 or len(username) > 20:
            register_error_message = '用户名长度必须在2-20个字符之间'
            return render(request, 'login.html', {
                'register_error_message': register_error_message,
                'show_register': True
            })

        # 密码长度验证 (3-20字符)
        if len(password) < 3 or len(password) > 20:
            register_error_message = '密码长度必须在3-20个字符之间'
            return render(request, 'login.html', {
                'register_error_message': register_error_message,
                'show_register': True
            })

        if password != password2:
            register_error_message = '密码不一致'
            return render(request, 'login.html', {
                'register_error_message': register_error_message,
                'show_register': True
            })
        else:
            user = User.objects.filter(username=username).first()
            if user:
                register_error_message = '账号已存在，请直接登录'
                return render(request, 'login.html', {
                    'register_error_message': register_error_message,
                    'show_register': True
                })
            else:
                # 检查邮箱是否已被使用
                if User.objects.filter(email=email).exists():
                    register_error_message = '该邮箱已被注册'
                    return render(request, 'login.html', {
                        'register_error_message': register_error_message,
                        'show_register': True
                    })

                # 创建用户
                User.objects.create_user(username=username, email=email, password=password)
                # 注册成功，显示登录表单并显示成功消息
                return render(request, 'login.html', {
                    'success_message': '注册成功！请使用您的邮箱登录。',
                    'show_login': True
                })

    # 处理重置密码请求
    elif 'reset_email' in request.POST:
        email = request.POST.get('reset_email', '').strip()
        code = request.POST.get('verify_code', '').strip()
        new_password = request.POST.get('new_password', '')
        confirm_new_password = request.POST.get('confirm_new_password', '')

        # 验证输入
        if not all([email, code, new_password, confirm_new_password]):
            return render(request, 'login.html', {
                'reset_error_message': '请填写所有字段',
                'show_forgot_password': True
            })

        # 验证密码一致性
        if new_password != confirm_new_password:
            return render(request, 'login.html', {
                'reset_error_message': '两次输入的密码不一致',
                'show_forgot_password': True
            })

        # 验证密码长度
        if len(new_password) < 4 or len(new_password) > 20:
            return render(request, 'login.html', {
                'reset_error_message': '密码长度必须在4-20个字符之间',
                'show_forgot_password': True
            })

        # 验证验证码
        try:
            reset_code = PasswordResetCode.objects.filter(
                email=email,
                code=code,
                is_used=False
            ).latest('created_at')

            if reset_code.is_expired():
                return render(request, 'login.html', {
                    'reset_error_message': '验证码已过期，请重新获取',
                    'show_forgot_password': True
                })

            # 验证码正确，重置密码
            user = User.objects.get(email=email)
            user.set_password(new_password)
            user.save()

            # 标记验证码为已使用
            reset_code.is_used = True
            reset_code.save()

            return render(request, 'login.html', {
                'reset_success_message': '密码重置成功！请使用新密码登录。',
                'show_login': True
            })

        except PasswordResetCode.DoesNotExist:
            return render(request, 'login.html', {
                'reset_error_message': '验证码错误或已使用',
                'show_forgot_password': True
            })
        except User.DoesNotExist:
            return render(request, 'login.html', {
                'reset_error_message': '该邮箱未注册',
                'show_forgot_password': True
            })

    # 处理登录请求 - 使用邮箱登录
    elif request.method == "POST":
        print("处理邮箱登录请求")

        # 获取邮箱和密码
        email = request.POST.get("email", "").strip()
        password = request.POST.get("password", "")

        print(f"登录尝试 - 邮箱: {email}, 密码长度: {len(password)}")

        # 验证邮箱格式
        if '@' not in email or '.' not in email:
            error_message = "请输入有效的邮箱地址"
            print(f"邮箱格式无效: {email}")
            return render(request, 'login.html', context={'error_message': error_message})

        # 通过邮箱查找用户
        try:
            user = User.objects.get(email=email)
            print(f"找到用户: {user.username}")

            if user.check_password(password):
                print("密码验证成功")
                auth_login(request, user)
                print("登录成功，重定向到首页")

                # 根据用户身份跳转到不同页面
                if user.is_staff or user.is_superuser:
                    return redirect('/user/admin_index/')
                else:
                    return redirect('/meet/index/')
            else:
                error_message = "密码不正确"
                print("密码验证失败")

        except User.DoesNotExist:
            error_message = "该邮箱未注册"
            print(f"用户不存在: {email}")
        except Exception as e:
            error_message = f"登录过程中发生错误: {str(e)}"
            print(f"登录异常: {str(e)}")

        return render(request, 'login.html', context={'error_message': error_message})

    # GET 请求 - 显示登录页面
    else:
        reset_success = request.GET.get('reset_success')
        context = {}
        if reset_success:
            context['success_message'] = '密码重置成功！请使用新密码登录。'
        return render(request, "login.html", context)


def register(request):
    """用户注册视图"""
    if request.method == 'GET':
        return render(request, 'register.html')
    elif request.method == 'POST':
        try:
            # 获取请求参数
            username = request.POST.get('username', '').strip()
            email = request.POST.get('email', '').strip()
            password = request.POST.get('password', '')
            password2 = request.POST.get('password2', '')
            email_verify_code = request.POST.get('email_verify_code', '').strip()

            print(f"注册请求 - 用户名: {username}, 邮箱: {email}")  # 调试日志

            # 验证输入完整性
            if not all([username, email, password, password2, email_verify_code]):
                return render(request, 'register.html', {'msg': '请填写所有字段'})

            # 比对密码
            if password != password2:
                return render(request, 'register.html', {'msg': '密码不匹配'})

            # 用户名长度验证 (2-20字符)
            if len(username) < 2 or len(username) > 20:
                return render(request, 'register.html', {'msg': '用户名长度必须在2-20个字符之间'})

            # 密码长度验证 (3-20字符)
            if len(password) < 3 or len(password) > 20:
                return render(request, 'register.html', {'msg': '密码长度必须在3-20个字符之间'})

            # 验证邮箱格式
            if '@' not in email or '.' not in email:
                return render(request, 'register.html', {'msg': '请输入有效的邮箱地址'})

            # 验证验证码
            try:
                verify_code = PasswordResetCode.objects.filter(
                    email=email,
                    code=email_verify_code,
                    is_used=False,
                ).latest('created_at')

                if verify_code.is_expired():
                    return render(request, 'register.html', {'msg': '验证码已过期，请重新获取'})

            except PasswordResetCode.DoesNotExist:
                return render(request, 'register.html', {'msg': '验证码错误或已使用'})

            # 查看当前用户是否已注册
            if User.objects.filter(username=username).exists():
                return render(request, 'register.html', {'msg': '用户名已存在，请直接登录'})

            # 查看邮箱是否已被使用
            if User.objects.filter(email=email).exists():
                return render(request, 'register.html', {'msg': '该邮箱已被注册'})

            # 注册用户
            user = User.objects.create_user(
                username=username,
                email=email,
                password=password
            )

            # 标记验证码为已使用
            verify_code.is_used = True
            verify_code.save()

            # 自动登录
            auth_login(request, user)

            print(f"用户注册成功: {username}")  # 调试日志
            return redirect('/meet/index/')

        except Exception as e:
            print(f"注册过程异常: {str(e)}")  # 调试日志
            return render(request, 'register.html', {'msg': f'注册失败: {str(e)}'})


def logout(request):
    """用户退出登录"""
    auth_logout(request)
    return redirect(to='/user/login/')


@csrf_exempt
def send_verify_code(request):
    if request.method == 'POST':
        email = request.POST.get('email', '').strip()
        code_type = request.POST.get('type', 'register')

        if not email:
            return JsonResponse({'success': False, 'message': '请输入邮箱地址'})

        # 检查邮箱格式
        if '@' not in email or '.' not in email:
            return JsonResponse({'success': False, 'message': '请输入有效的邮箱地址'})

        # 根据类型进行不同的验证
        if code_type == 'register':
            # 注册时检查邮箱是否已被使用
            if User.objects.filter(email=email).exists():
                return JsonResponse({'success': False, 'message': '该邮箱已被注册'})
        else:  # reset
            # 重置密码时检查邮箱是否已注册
            if not User.objects.filter(email=email).exists():
                return JsonResponse({'success': False, 'message': '该邮箱未注册'})

        # 检查是否在1分钟内重复发送
        one_minute_ago = timezone.now() - timedelta(minutes=1)
        recent_codes = PasswordResetCode.objects.filter(
            email=email,
            created_at__gte=one_minute_ago,
            is_used=False
        )
        if recent_codes.exists():
            return JsonResponse({'success': False, 'message': '请等待1分钟后再重新发送验证码'})

        # 生成并保存验证码
        verify_code = PasswordResetCode.generate_code(email)

        # 发送邮件
        try:
            if code_type == 'register':
                subject = '城会玩系统 - 注册验证码'
                message = f"""
                您好！

                欢迎注册城会玩系统，您的注册验证码是：

                【{verify_code.code}】

                验证码有效期为10分钟，请尽快使用。

                如果这不是您本人的操作，请忽略此邮件。

                祝您创作愉快！
                城会玩系统团队
                """
            else:
                subject = '城会玩系统 - 密码重置验证码'
                message = f"""
                您好！

                您正在尝试重置城会玩系统的密码，您的验证码是：

                【{verify_code.code}】

                验证码有效期为10分钟，请尽快使用。

                如果这不是您本人的操作，请忽略此邮件。

                祝您使用愉快！
                城会玩系统团队
                """

            from_email = settings.DEFAULT_FROM_EMAIL
            recipient_list = [email]

            send_mail(
                subject=subject,
                message=message,
                from_email=from_email,
                recipient_list=recipient_list,
                fail_silently=False,
            )

            print(f"验证码邮件发送成功 - 收件人: {email}, 验证码: {verify_code.code}, 类型: {code_type}")
            return JsonResponse({'success': True, 'message': '验证码已发送到您的邮箱'})

        except Exception as e:
            # 如果出现异常，删除验证码记录
            verify_code.delete()
            print(f"发送验证码异常: {str(e)}")
            return JsonResponse({'success': False, 'message': f'邮件发送失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})

@login_required
def person_center(request):
    """
    个人中心视图 - 修复版
    """
    user = request.user

    # 获取用户档案信息
    try:
        profile = UserProfile.objects.select_related('user').get(user=user)
    except UserProfile.DoesNotExist:
        profile = UserProfile.objects.create(user=user)

    # 确保用户有默认的兴趣标签
    if not user.interests:
        user.interests = []
        user.save()

    # 获取统计信息
    organized_count = Activity.objects.filter(organizer=user).count()
    joined_count = ActivityParticipation.objects.filter(
        user=user,
        status__in=['registered', 'attended']
    ).count()
    following_count = UserFollow.objects.filter(follower=user).count()
    followers_count = UserFollow.objects.filter(following=user).count()

    # 构建上下文数据 - 使用安全的头像URL
    context = {
        'user': user,
        'profile': profile,
        'organized_count': organized_count,
        'joined_count': joined_count,
        'following_count': following_count,
        'followers_count': followers_count,
        'avatar_url': user.get_avatar_url(),  # 添加安全的头像URL
    }

    return render(request, 'person_center.html', context)

@login_required
def talking(request):
    """
    独立聊天页面视图
    """
    user = request.user

    # 获取用户加入的聊天群组
    chat_groups = get_user_chat_groups(user)

    # 获取最近私信
    recent_messages = get_recent_messages(user)

    context = {
        'user': user,
        'chat_groups': chat_groups,
        'recent_messages': recent_messages,
    }

    return render(request, 'talking.html', context)

def get_avatar_url(user):
    """安全地获取用户头像URL"""
    try:
        if user.avatar:
            # 确保我们获取的是字符串URL，而不是ContentFile对象
            if hasattr(user.avatar, 'url'):
                return user.avatar.url
            else:
                # 如果是字符串，直接返回
                return str(user.avatar)
        else:
            # 返回默认头像URL
            return '/static/images/default-avatar.png'
    except Exception as e:
        print(f"获取头像URL失败: {str(e)}")
        return '/static/images/default-avatar.png'


def get_following_list(request):
    """获取关注列表"""
    try:
        # 获取当前用户的关注关系
        following_relationships = UserFollow.objects.filter(follower=request.user).select_related('following')

        following_users = []
        for relationship in following_relationships:
            user = relationship.following

            # 获取用户头像URL - 使用Cloudinary的URL生成
            if user.avatar:
                # CloudinaryField会自动提供URL
                avatar_url = user.avatar.url
            else:
                # 使用默认头像
                avatar_url = '/static/images/default-avatar.png'

            user_data = {
                'id': user.id,
                'username': user.username,
                'bio': user.bio or '这个用户很懒，还没有写个人简介...',
                'avatar': avatar_url,
                'registration_date': user.date_joined.strftime('%Y-%m-%d'),
                'created_at': relationship.created_at.strftime('%Y-%m-%d'),
                'interests': user.interests if user.interests else []
            }
            following_users.append(user_data)

        return JsonResponse({'success': True, 'users': following_users})

    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})

@login_required
@csrf_exempt
def upload_avatar(request):
    """专门处理头像上传 - 修复版"""
    if request.method == 'POST':
        try:
            user = request.user
            print(f"开始处理头像上传，用户: {user.username}")

            # 处理文件上传
            if 'avatar' in request.FILES:
                print("通过文件上传处理头像")
                avatar_file = request.FILES['avatar']

                # 验证文件类型
                if not avatar_file.content_type.startswith('image/'):
                    return JsonResponse({'success': False, 'message': '请上传图片文件'})

                # 验证文件大小（限制为5MB）
                if avatar_file.size > 5 * 1024 * 1024:
                    return JsonResponse({'success': False, 'message': '图片大小不能超过5MB'})

                # 保存头像
                try:
                    user.avatar = avatar_file
                    user.save()

                    # 获取头像URL
                    avatar_url = user.get_avatar_url()
                    print(f"文件上传成功，头像URL: {avatar_url}")

                    return JsonResponse({
                        'success': True,
                        'avatar_url': avatar_url,
                        'message': '头像上传成功'
                    })

                except Exception as upload_error:
                    print(f"头像上传错误: {str(upload_error)}")
                    return JsonResponse({
                        'success': False,
                        'message': f'头像上传失败: {str(upload_error)}'
                    })

            # 处理 base64 图片
            elif request.content_type == 'application/json':
                print("通过base64处理头像")
                data = json.loads(request.body)

                if 'avatar' in data and data['avatar'].startswith('data:image'):
                    format, imgstr = data['avatar'].split(';base64,')
                    ext = format.split('/')[-1]

                    # 验证文件类型
                    if ext.lower() not in ['jpg', 'jpeg', 'png', 'gif']:
                        return JsonResponse({'success': False, 'message': '不支持的图片格式'})

                    # 解码base64数据
                    try:
                        image_data = base64.b64decode(imgstr)
                    except Exception as e:
                        return JsonResponse({'success': False, 'message': '图片数据格式错误'})

                    # 验证文件大小
                    if len(image_data) > 5 * 1024 * 1024:
                        return JsonResponse({'success': False, 'message': '图片大小不能超过5MB'})

                    # 创建文件名
                    filename = f'avatar_{user.id}_{int(timezone.now().timestamp())}.{ext}'

                    # 创建 ContentFile
                    from django.core.files.base import ContentFile
                    avatar_content = ContentFile(image_data, name=filename)

                    try:
                        # 保存头像
                        user.avatar = avatar_content
                        user.save()

                        avatar_url = user.get_avatar_url()
                        print(f"Base64上传成功，头像URL: {avatar_url}")

                        return JsonResponse({
                            'success': True,
                            'avatar_url': avatar_url,
                            'message': '头像更新成功'
                        })

                    except Exception as upload_error:
                        print(f"Base64上传错误: {str(upload_error)}")
                        return JsonResponse({
                            'success': False,
                            'message': f'头像上传失败: {str(upload_error)}'
                        })
                else:
                    return JsonResponse({'success': False, 'message': '无效的图片数据'})

            return JsonResponse({'success': False, 'message': '未找到头像数据'})

        except Exception as e:
            print(f"头像上传异常: {str(e)}")
            import traceback
            print(f"详细错误: {traceback.format_exc()}")
            return JsonResponse({'success': False, 'message': f'头像上传失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})

@login_required
@require_http_methods(["POST"])
def cancel_participation(request, activity_id):
    """
    取消活动报名
    """
    try:
        user = request.user

        # 查找用户的报名记录
        participation = ActivityParticipation.objects.get(
            user=user,
            activity_id=activity_id,
            status__in=['registered']  # 只能取消已报名但未参加的活动
        )

        activity = participation.activity

        # 检查活动是否已经开始
        if activity.start_time <= timezone.now():
            return JsonResponse({
                'success': False,
                'message': '活动已开始，无法取消报名'
            })

        # 删除报名记录
        participation.delete()

        # 更新活动的当前参与人数
        activity.current_participants = ActivityParticipation.objects.filter(
            activity=activity,
            status__in=['registered', 'attended']
        ).count()
        activity.save()

        return JsonResponse({
            'success': True,
            'message': '成功取消报名'
        })

    except ActivityParticipation.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '未找到报名记录或已取消'
        })
    except Exception as e:
        print(f"取消报名失败: {str(e)}")
        return JsonResponse({
            'success': False,
            'message': f'取消报名失败: {str(e)}'
        })


def get_followers_list(request):
    """获取粉丝列表"""
    try:
        # 获取当前用户的粉丝关系
        follower_relationships = UserFollow.objects.filter(following=request.user).select_related('follower')

        followers_users = []
        for relationship in follower_relationships:
            user = relationship.follower

            # 检查当前用户是否也关注了这个粉丝（互相关注）
            is_following_back = UserFollow.objects.filter(
                follower=request.user,
                following=user
            ).exists()

            # 获取用户头像URL
            if user.avatar:
                avatar_url = user.avatar.url
            else:
                avatar_url = '/static/images/default-avatar.png'

            user_data = {
                'id': user.id,
                'username': user.username,
                'bio': user.bio or '这个用户很懒，还没有写个人简介...',
                'avatar': avatar_url,
                'registration_date': user.date_joined.strftime('%Y-%m-%d'),
                'created_at': relationship.created_at.strftime('%Y-%m-%d'),
                'is_following_back': is_following_back
            }
            followers_users.append(user_data)

        return JsonResponse({'success': True, 'users': followers_users})

    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})

@login_required
@csrf_exempt
def update_profile(request):
    if request.method == 'POST':
        try:
            user = request.user
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST

            # 更新用户名
            new_username = data.get('username', '').strip()
            if new_username and new_username != user.username:
                # 检查用户名是否已存在
                if User.objects.filter(username=new_username).exclude(id=user.id).exists():
                    return JsonResponse({'success': False, 'message': '用户名已存在'})
                user.username = new_username

            # 更新邮箱
            new_email = data.get('email', '').strip()
            if new_email and new_email != user.email:
                # 检查邮箱是否已存在
                if User.objects.filter(email=new_email).exclude(id=user.id).exists():
                    return JsonResponse({'success': False, 'message': '邮箱已被使用'})
                user.email = new_email

            # 更新手机号 - 修复唯一性约束问题
            new_phone = data.get('phone', '').strip()
            if new_phone:
                # 如果新手机号与当前不同，检查是否已被使用
                if new_phone != user.phone:
                    if User.objects.filter(phone=new_phone).exclude(id=user.id).exists():
                        return JsonResponse({'success': False, 'message': '手机号已被使用'})
                    user.phone = new_phone
            else:
                # 如果手机号为空，设置为None而不是空字符串
                user.phone = None

            # 更新个性签名
            new_bio = data.get('bio', '').strip()
            if new_bio is not None:
                user.bio = new_bio

            # 更新兴趣标签
            interests = data.get('interests', '')
            if interests:
                if isinstance(interests, str):
                    # 如果是字符串，按逗号分割
                    interests_list = [interest.strip() for interest in interests.split(',') if interest.strip()]
                else:
                    interests_list = interests
                user.interests = interests_list

            # 保存用户信息
            user.save()

            # 更新用户档案信息
            try:
                profile = UserProfile.objects.get(user=user)
            except UserProfile.DoesNotExist:
                profile = UserProfile.objects.create(user=user)

            # 更新性别
            gender = data.get('gender', '')
            if gender in ['male', 'female', 'other']:
                profile.gender = gender

            # 更新生日
            birthday = data.get('birthday', '')
            if birthday:
                try:
                    from datetime import datetime
                    profile.birthday = datetime.strptime(birthday, '%Y-%m-%d').date()
                except ValueError:
                    pass

            # 更新所在地
            location = data.get('location', '').strip()
            if location:
                profile.location = location

            profile.save()

            return JsonResponse({
                'success': True,
                'message': '个人信息更新成功',
                'user': {
                    'username': user.username,
                    'email': user.email,
                    'phone': user.phone if user.phone else '未设置',
                    'bio': user.bio if user.bio else '这个用户很懒，还没有写个人简介...',
                    'interests': user.interests,
                    'avatar_url': user.avatar.url if user.avatar else '/media/avatars/default-avatar.png'
                },
                'profile': {
                    'gender': profile.get_gender_display() if profile.gender else '未设置',
                    'birthday': profile.birthday.strftime('%Y-%m-%d') if profile.birthday else '未设置',
                    'location': profile.location if profile.location else '未设置'
                }
            })

        except Exception as e:
            print(f"更新个人信息错误: {str(e)}")
            return JsonResponse({'success': False, 'message': f'信息更新失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


def section_data(request, section):
    """根据section参数返回不同的数据 - 完整修复版"""
    try:
        if section == 'following':
            return get_following_list(request)
        elif section == 'followers':
            return get_followers_list(request)
        elif section == 'my-activities':
            # 返回用户发布的活动
            return get_my_activities(request)
        elif section == 'joined-activities':
            # 返回用户参与的活动
            return get_joined_activities(request)
        elif section == 'private-messages':
            # 新增：返回私信相关数据
            return get_private_messages_data(request)
        else:
            return JsonResponse({
                'success': False,
                'message': f'未知的section: {section}',
                'available_sections': ['following', 'followers', 'my-activities', 'joined-activities', 'private-messages']
            }, status=400)
    except Exception as e:
        import traceback
        error_details = traceback.format_exc()
        print(f"section_data 错误: {str(e)}")
        print(f"详细错误: {error_details}")
        return JsonResponse({
            'success': False,
            'error': '加载数据时发生错误',
            'debug_info': str(e)
        }, status=500)


def get_private_messages_data(request):
    """获取私信相关数据"""
    try:
        user = request.user
        # 获取用户加入的聊天群组
        chat_groups = get_user_chat_groups(user)
        # 获取最近私信
        recent_messages = get_recent_messages(user)
        # 获取消息通知
        notifications = get_message_notifications(user)
        return JsonResponse({
            'success': True,
            'chat_groups': chat_groups,
            'recent_messages': recent_messages,
            'notifications': notifications
        })
    except Exception as e:
        print(f"获取私信数据失败: {str(e)}")
        return JsonResponse({
            'success': False,
            'message': f'加载数据失败: {str(e)}'
        }, status=500)

@login_required
@require_http_methods(["POST"])
@csrf_exempt
def cancel_activity(request, activity_id):
    """取消用户发布的活动"""
    try:
        activity = get_object_or_404(Activity, id=activity_id, organizer=request.user)

        # 检查是否可以取消
        if activity.status not in ['draft', 'pending', 'published']:
            return JsonResponse({
                'success': False,
                'message': '该活动无法取消'
            })

        # 更新活动状态
        activity.status = 'cancelled'
        activity.cancel_reason = '活动发起者取消'
        activity.save()

        # 通知参与者
        # 这里可以添加通知逻辑

        return JsonResponse({
            'success': True,
            'message': '活动已成功取消'
        })

    except Activity.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '活动不存在或无权操作'
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'取消活动失败: {str(e)}'
        })


@login_required
@require_http_methods(["POST"])
@csrf_exempt
def delete_activity(request, activity_id):
    """删除用户发布的活动（软删除）"""
    try:
        activity = get_object_or_404(Activity, id=activity_id, organizer=request.user)

        # 检查是否可以删除
        if activity.status not in ['draft', 'cancelled']:
            return JsonResponse({
                'success': False,
                'message': '只能删除草稿或已取消的活动'
            })

        # 软删除：标记为删除状态
        activity.is_active = False
        activity.save()

        return JsonResponse({
            'success': True,
            'message': '活动已删除'
        })

    except Activity.DoesNotExist:
        return JsonResponse({
            'success': False,
            'message': '活动不存在或无权操作'
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'删除活动失败: {str(e)}'
        })


@login_required
def get_my_activities(request):
    """获取用户发布的活动 - 简化版本"""
    try:
        user = request.user
        activities = Activity.objects.filter(organizer=user).order_by('-created_at')

        activities_data = []
        for activity in activities:
            # 直接使用模型字段
            activities_data.append({
                'id': activity.id,
                'title': activity.title,
                'description': activity.description or '暂无描述',
                'category': activity.category.name if activity.category else '未分类',
                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M') if activity.start_time else '时间待定',
                'location_name': activity.location_name or '地点待定',
                'cover_image': activity.image.url if activity.image and hasattr(activity.image,
                                                                                'url') else '/static/images/default-activity.jpg',
                'status': activity.status,
                'status_display': dict(Activity.STATUS_CHOICES).get(activity.status, activity.status),
                'current_participants': activity.current_participants,
                'max_participants': activity.max_participants,
            })

        return JsonResponse({
            'success': True,
            'activities': activities_data
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取活动数据失败: {str(e)}'
        }, status=500)


@login_required
def get_joined_activities(request):
    """获取用户参与的活动 - 简化版本"""
    try:
        user = request.user
        participations = ActivityParticipation.objects.filter(user=user).select_related('activity')

        activities_data = []
        for participation in participations:
            activity = participation.activity

            activities_data.append({
                'id': activity.id,
                'title': activity.title,
                'description': activity.description or '暂无描述',
                'category': activity.category.name if activity.category else '未分类',
                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M') if activity.start_time else '时间待定',
                'location_name': activity.location_name or '地点待定',
                'cover_image': activity.image.url if activity.image and hasattr(activity.image,
                                                                                'url') else '/static/images/default-activity.jpg',
                'status': activity.status,
                'status_display': dict(Activity.STATUS_CHOICES).get(activity.status, activity.status),
                'participation_status': participation.status,
                'participation_status_display': {
                    'registered': '已报名',
                    'attended': '已参加',
                    'cancelled': '已取消'
                }.get(participation.status, participation.status),
                'current_participants': activity.current_participants,
                'max_participants': activity.max_participants,
            })

        return JsonResponse({
            'success': True,
            'activities': activities_data
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'获取参与活动数据失败: {str(e)}'
        }, status=500)


def get_user_chat_groups(user):
    """获取用户加入的聊天群组 - 修复头像URL"""
    groups = ChatGroup.objects.filter(
        members=user,
        is_active=True
    ).annotate(
        member_count=Count('members')
    ).order_by('-updated_at')

    groups_data = []
    for group in groups:
        try:
            last_message = group.messages.order_by('-created_at').first()

            groups_data.append({
                'id': group.id,
                'name': group.name,
                'avatar': get_safe_avatar_url(group, is_group=True),  # 使用修复后的函数
                'description': group.description,
                'member_count': group.member_count,
                'last_message': last_message.content[:50] + '...' if last_message and len(
                    last_message.content) > 50 else (last_message.content if last_message else '暂无消息'),
                'last_message_time': last_message.created_at.isoformat() if last_message else '',
                'is_owner': group.creator == user,
            })
        except Exception as e:
            logger.error(f"处理群组数据失败: {e}")
            continue

    return groups_data


def get_safe_avatar_url(user, is_group=False):
    """安全地获取头像URL"""
    try:
        if hasattr(user, 'avatar') and user.avatar:
            return user.avatar.url
    except Exception as e:
        logger.error(f"获取头像URL异常: {e}")

    # 回退到静态默认头像
    return '/static/images/default-group-avatar.png' if is_group else '/static/images/default-avatar.png'

@login_required
@csrf_exempt
def create_chat_group(request):
    """创建聊天群组"""
    if request.method == 'POST':
        try:
            user = request.user
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST

            name = data.get('name', '').strip()
            description = data.get('description', '').strip()
            max_members = data.get('max_members', 50)

            if not name:
                return JsonResponse({'success': False, 'message': '群组名称不能为空'})

            # 创建群组
            group = ChatGroup.objects.create(
                name=name,
                description=description,
                creator=user,
                max_members=max_members
            )

            # 添加创建者为群主
            GroupMembership.objects.create(
                group=group,
                user=user,
                role='owner'
            )

            return JsonResponse({
                'success': True,
                'message': '群组创建成功',
                'group_id': group.id,
                'group_name': group.name
            })

        except Exception as e:
            return JsonResponse({'success': False, 'message': f'创建群组失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@login_required
@csrf_exempt
def invite_to_group(request):
    """邀请用户加入群组"""
    if request.method == 'POST':
        try:
            user = request.user
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST

            group_id = data.get('group_id')
            user_ids = data.get('user_ids', [])

            if isinstance(user_ids, str):
                try:
                    user_ids = json.loads(user_ids)
                except json.JSONDecodeError:
                    user_ids = [user_ids]

            if not group_id or not user_ids:
                return JsonResponse({'success': False, 'message': '缺少必要参数'})

            group = ChatGroup.objects.get(id=group_id)

            # 检查用户是否有邀请权限
            try:
                user_membership = GroupMembership.objects.get(group=group, user=user)
                if user_membership.role not in ['owner', 'admin']:
                    return JsonResponse({'success': False, 'message': '没有权限邀请用户'})
            except GroupMembership.DoesNotExist:
                return JsonResponse({'success': False, 'message': '您不在该群组中'})

            # 检查群组人数限制
            current_member_count = group.members.count()
            if current_member_count + len(user_ids) > group.max_members:
                return JsonResponse({
                    'success': False,
                    'message': f'群组人数已达上限，当前{current_member_count}/{group.max_members}人'
                })

            invited_users = []
            failed_users = []

            for user_id in user_ids:
                try:
                    invite_user = User.objects.get(id=user_id)

                    # 检查用户是否已经在群组中
                    if GroupMembership.objects.filter(group=group, user=invite_user).exists():
                        failed_users.append(f"{invite_user.username}（已在群组中）")
                        continue

                    # 添加用户到群组
                    GroupMembership.objects.create(
                        group=group,
                        user=invite_user,
                        role='member'
                    )
                    invited_users.append(invite_user.username)

                    # 发送系统消息通知
                    GroupMessage.objects.create(
                        group=group,
                        sender=user,  # 系统消息由邀请者发送
                        content=f'{user.username} 邀请了 {invite_user.username} 加入群组',
                        message_type='system'
                    )

                except User.DoesNotExist:
                    failed_users.append(f"用户ID:{user_id}（不存在）")

            # 更新群组最后活动时间
            group.updated_at = timezone.now()
            group.save()

            message = f'成功邀请 {len(invited_users)} 个用户'
            if failed_users:
                message += f'，失败 {len(failed_users)} 个：{", ".join(failed_users)}'

            return JsonResponse({
                'success': True,
                'message': message,
                'invited_users': invited_users,
                'failed_users': failed_users
            })

        except ChatGroup.DoesNotExist:
            return JsonResponse({'success': False, 'message': '群组不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'邀请失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@login_required
@csrf_exempt
def send_chat_message(request):
    """发送聊天消息 - 完整实现"""
    if request.method == 'POST':
        try:
            user = request.user
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST

            chat_type = data.get('type', 'private')
            target_id = data.get('target_id')
            content = data.get('content', '').strip()

            if not all([target_id, content]):
                return JsonResponse({'success': False, 'message': '缺少必要参数'})

            if chat_type == 'private':
                # 私聊消息
                receiver = User.objects.get(id=target_id)
                message = PrivateMessage.objects.create(
                    sender=user,
                    receiver=receiver,
                    content=content
                )

            elif chat_type == 'group':
                # 群聊消息
                group = ChatGroup.objects.get(id=target_id)

                # 检查用户是否在群组中
                if not GroupMembership.objects.filter(group=group, user=user).exists():
                    return JsonResponse({'success': False, 'message': '您不在该群组中'})

                # 检查用户是否被禁言
                membership = GroupMembership.objects.get(group=group, user=user)
                if membership.is_muted:
                    return JsonResponse({'success': False, 'message': '您已被禁言，无法发送消息'})

                message = GroupMessage.objects.create(
                    group=group,
                    sender=user,
                    content=content,
                    message_type='text'
                )

                # 更新群组更新时间
                group.updated_at = timezone.now()
                group.save()

            return JsonResponse({
                'success': True,
                'message': '发送成功',
                'message_id': message.id,
                'created_at': message.created_at.strftime('%Y-%m-%d %H:%M')
            })

        except User.DoesNotExist:
            return JsonResponse({'success': False, 'message': '用户不存在'})
        except ChatGroup.DoesNotExist:
            return JsonResponse({'success': False, 'message': '群组不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'发送失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@staff_member_required
def admin_index(request):
    """简化的管理员仪表板"""
    # 获取当前标签页
    current_tab = request.GET.get('tab', 'dashboard')

    # 基础统计
    total_users = User.objects.count()
    total_activities = Activity.objects.count()
    total_participations = ActivityParticipation.objects.count()

    # 今日统计
    today = timezone.now().date()
    today_users = User.objects.filter(date_joined__date=today).count()
    today_activities = Activity.objects.filter(created_at__date=today).count()

    # 活动状态统计 - 添加待审核统计
    activity_status_stats = Activity.objects.values('status').annotate(count=Count('id'))

    # 待审核活动数量
    pending_activities_count = Activity.objects.filter(status='pending').count()

    # 热门活动
    popular_activities = Activity.objects.filter(status='published').order_by('-current_participants')[:5]

    # 活跃用户
    active_users = User.objects.annotate(
        activity_count=Count('organized_activities')
    ).filter(activity_count__gt=0).order_by('-activity_count')[:5]

    # 用户管理数据
    users = User.objects.all().order_by('-date_joined')
    user_search = request.GET.get('user_search', '')
    user_status = request.GET.get('user_status', '')

    if user_search:
        users = users.filter(
            Q(username__icontains=user_search) |
            Q(email__icontains=user_search) |
            Q(phone__icontains=user_search)
        )

    if user_status == 'active':
        users = users.filter(is_active=True)
    elif user_status == 'inactive':
        users = users.filter(is_active=False)
    elif user_status == 'staff':
        users = users.filter(is_staff=True)

    # 用户分页
    user_paginator = Paginator(users, 10)
    user_page_number = request.GET.get('user_page', 1)
    user_page = user_paginator.get_page(user_page_number)

    # 活动管理数据 - 默认显示所有活动，包括待审核的
    activities = Activity.objects.all().select_related('category', 'organizer').order_by('-created_at')
    activity_search = request.GET.get('activity_search', '')
    activity_status_filter = request.GET.get('activity_status_filter', '')
    activity_category = request.GET.get('activity_category', '')

    if activity_search:
        activities = activities.filter(
            Q(title__icontains=activity_search) |
            Q(description__icontains=activity_search) |
            Q(location_name__icontains=activity_search)
        )

    if activity_status_filter:
        activities = activities.filter(status=activity_status_filter)

    if activity_category:
        activities = activities.filter(category_id=activity_category)

    # 活动分页
    activity_paginator = Paginator(activities, 10)
    activity_page_number = request.GET.get('activity_page', 1)
    activity_page = activity_paginator.get_page(activity_page_number)

    # 分类数据
    categories = ActivityCategory.objects.filter(is_active=True)

    context = {
        'current_tab': current_tab,

        # 仪表板数据
        'total_users': total_users,
        'total_activities': total_activities,
        'total_participations': total_participations,
        'today_users': today_users,
        'today_activities': today_activities,
        'activity_status_stats': activity_status_stats,
        'pending_activities_count': pending_activities_count,  # 新增
        'popular_activities': popular_activities,
        'active_users': active_users,

        # 用户管理数据
        'users': user_page,
        'user_search': user_search,
        'user_status': user_status,

        # 活动管理数据
        'activities': activity_page,
        'categories': categories,
        'activity_search': activity_search,
        'activity_status_filter': activity_status_filter,
        'activity_category': activity_category,
    }

    return render(request, 'admin_index.html', context)


def admin_redirect(request):
    """重定向到管理员后台"""
    return redirect('/user/admin_index/')


@staff_member_required
@require_http_methods(["POST"])
def ban_user(request, user_id):
    """封禁用户"""
    try:
        user = User.objects.get(id=user_id)
        days = int(request.POST.get('days', 7))  # 默认封禁7天
        reason = request.POST.get('reason', '违反社区规定')

        user.account_status = 'banned'
        user.banned_until = timezone.now() + timedelta(days=days)
        user.ban_reason = reason
        user.is_active = False  # 使其无法登录
        user.save()

        return JsonResponse({'success': True, 'message': f'用户 {user.username} 已被封禁'})
    except User.DoesNotExist:
        return JsonResponse({'success': False, 'message': '用户不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def unban_user(request, user_id):
    """解封用户"""
    try:
        user = User.objects.get(id=user_id)
        user.account_status = 'active'
        user.banned_until = None
        user.ban_reason = ''
        user.is_active = True
        user.save()

        return JsonResponse({'success': True, 'message': f'用户 {user.username} 已解封'})
    except User.DoesNotExist:
        return JsonResponse({'success': False, 'message': '用户不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def delete_user(request, user_id):
    """删除用户（软删除）"""
    try:
        user = User.objects.get(id=user_id)
        user.account_status = 'deleted'
        user.is_active = False
        user.username = f"deleted_{user.id}_{int(timezone.now().timestamp())}"
        user.email = f"deleted_{user.id}@deleted.com"
        user.save()

        return JsonResponse({'success': True, 'message': f'用户已删除'})
    except User.DoesNotExist:
        return JsonResponse({'success': False, 'message': '用户不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def approve_activity(request, activity_id):
    """批准活动"""
    try:
        activity = Activity.objects.get(id=activity_id)

        if activity.status != 'pending':
            return JsonResponse({'success': False, 'message': '只能批准待审核的活动'})

        activity.status = 'published'
        activity.save()

        return JsonResponse({'success': True, 'message': f'活动 "{activity.title}" 已批准并发布'})
    except Activity.DoesNotExist:
        return JsonResponse({'success': False, 'message': '活动不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def reject_activity(request, activity_id):
    """拒绝活动"""
    try:
        activity = Activity.objects.get(id=activity_id)
        reason = request.POST.get('reason', '活动内容不符合社区规范')

        if activity.status != 'pending':
            return JsonResponse({'success': False, 'message': '只能拒绝待审核的活动'})

        activity.status = 'cancelled'
        activity.cancel_reason = f'管理员拒绝: {reason}'
        activity.save()

        return JsonResponse({'success': True, 'message': f'活动 "{activity.title}" 已拒绝'})
    except Activity.DoesNotExist:
        return JsonResponse({'success': False, 'message': '活动不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def delete_activity(request, activity_id):
    """删除活动"""
    try:
        activity = Activity.objects.get(id=activity_id)
        activity_title = activity.title

        # 删除相关的参与记录
        ActivityParticipation.objects.filter(activity=activity).delete()

        # 删除活动
        activity.delete()

        return JsonResponse({'success': True, 'message': f'活动 "{activity_title}" 已删除'})
    except Activity.DoesNotExist:
        return JsonResponse({'success': False, 'message': '活动不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


# 在 get_section_data 函数中添加新的分支
@login_required
def get_section_data(request, section_name):
    """
    获取各个部分的动态数据 - 用于异步加载
    """
    user = request.user

    if section_name == 'my-activities':
        # 获取用户发布的活动
        activities = Activity.objects.filter(organizer=user).order_by('-created_at')
        activities_data = []
        for activity in activities:
            activities_data.append({
                'id': activity.id,
                'title': activity.title,
                'category': activity.category.name if activity.category else '其他',
                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M') if activity.start_time else '时间待定',
                'location_name': activity.location_name or '地点待定',
                'current_participants': activity.current_participants or 0,
                'max_participants': activity.max_participants or 0,
                'status': activity.status,
                'cover_image': activity.cover_image.url if activity.cover_image else '/static/images/default-activity.jpg',
                'description': activity.description[:100] + '...' if activity.description and len(
                    activity.description) > 100 else (activity.description or '暂无描述')
            })
        return JsonResponse({'activities': activities_data})


    elif section_name == 'joined-activities':
        # 获取用户参与的活动
        participations = ActivityParticipation.objects.filter(
            user=user,
            status__in=['registered', 'attended']
        ).select_related('activity')
        activities_data = []
        for participation in participations:
            activity = participation.activity

            activities_data.append({

                'id': activity.id,

                'title': activity.title,

                'category': activity.category.name if activity.category else '其他',

                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M') if activity.start_time else '时间待定',

                'location_name': activity.location_name or '地点待定',

                'status': activity.status,

                'participation_status': participation.status,

                'image_url': activity.image.url if activity.image else None,

                'description': activity.description[:100] + '...' if activity.description and len(
                    activity.description) > 100 else (activity.description or '暂无描述'),

                'current_participants': activity.current_participants or 0,

                'max_participants': activity.max_participants or 0,

            })

        return JsonResponse({'activities': activities_data})


    elif section_name == 'following':

        # 获取关注列表 - 统一使用 UserFollow

        relationships = UserFollow.objects.filter(

            follower=user

        ).select_related('following')

        data = []

        for relationship in relationships:

            following_user = relationship.following

            data.append({

                'id': following_user.id,

                'username': following_user.username,

                'bio': following_user.bio or '这个用户很懒，还没有写个人简介...',

                'avatar': following_user.avatar.url if following_user.avatar else '/media/avatars/default-avatar.png',

                'interests': following_user.interests,

                'registration_date': following_user.date_joined.strftime('%Y-%m-%d'),

                'created_at': relationship.created_at.strftime('%Y-%m-%d')

            })

        return JsonResponse({'users': data})

    elif section_name == 'followers':
        # 获取粉丝列表 - 统一使用 UserFollow
        relationships = UserFollow.objects.filter(
            following=user
        ).select_related('follower')
        data = []
        for relationship in relationships:
            follower_user = relationship.follower
            # 检查是否互相关注
            is_following_back = UserFollow.objects.filter(
                follower=user,
                following=follower_user
            ).exists()

            data.append({
                'id': follower_user.id,
                'username': follower_user.username,
                'avatar': follower_user.avatar.url if follower_user.avatar else '/media/avatars/default-avatar.png',
                'bio': follower_user.bio or '这个用户很懒，还没有写个人简介...',
                'registration_date': follower_user.date_joined.strftime('%Y-%m-%d'),
                'created_at': relationship.created_at.strftime('%Y-%m-%d %H:%M'),
                'is_following_back': is_following_back
            })
        return JsonResponse({'users': data})

    elif section_name == 'private-messages':
        # 获取私信相关数据
        return JsonResponse({
            'notifications': get_message_notifications(user),
            'recent_messages': get_recent_messages(user),
            'chat_groups': get_user_chat_groups(user)
        })
    return JsonResponse({'error': '未知的请求部分'})


# 新增函数：获取消息通知
def get_message_notifications(user):
    """获取未读消息和新增关注通知"""
    # 未读私信数量
    unread_messages_count = PrivateMessage.objects.filter(
        receiver=user,
        is_read=False
    ).count()

    # 新增关注数量（最近7天）
    recent_followers_count = UserRelationship.objects.filter(
        following=user,
        created_at__gte=timezone.now() - timedelta(days=7)
    ).count()

    return {
        'unread_messages': unread_messages_count,
        'recent_followers': recent_followers_count
    }


# 新增函数：获取最近消息
def get_recent_messages(user):
    """获取最近的私信对话 - 修复版本"""
    try:
        # 获取最近有私信往来的用户
        recent_conversations = PrivateMessage.objects.filter(
            Q(sender=user) | Q(receiver=user)
        ).values('sender', 'receiver').distinct()

        # 使用字典按用户ID去重
        user_conversations = {}

        for conv in recent_conversations[:20]:  # 限制20个最近对话
            other_user_id = conv['receiver'] if conv['sender'] == user.id else conv['sender']

            # 如果该用户已经存在，跳过重复
            if other_user_id in user_conversations:
                continue

            try:
                other_user = User.objects.get(id=other_user_id)
                last_message = PrivateMessage.objects.filter(
                    Q(sender=user, receiver=other_user) | Q(sender=other_user, receiver=user)
                ).order_by('-created_at').first()

                # 计算未读消息数量
                unread_count = PrivateMessage.objects.filter(
                    sender=other_user,
                    receiver=user,
                    is_read=False
                ).count()

                user_conversations[other_user_id] = {
                    'user_id': other_user.id,
                    'username': other_user.username,
                    'avatar': get_avatar_url(other_user),
                    'last_message': last_message.content[:50] + '...' if last_message and len(
                        last_message.content) > 50 else (last_message.content if last_message else ''),
                    'last_message_time': last_message.created_at.isoformat() if last_message else '',
                    'unread_count': unread_count
                }
            except User.DoesNotExist:
                continue

        return list(user_conversations.values())

    except Exception as e:
        print(f"获取最近消息失败: {str(e)}")
        return []


# 新增函数：搜索用户
@login_required
@csrf_exempt
def search_users(request):
    """搜索用户"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST
            search_query = data.get('query', '').strip()

            if not search_query:
                return JsonResponse({'success': False, 'message': '请输入搜索关键词'})

            # 搜索用户（排除自己）
            users = User.objects.filter(
                Q(username__icontains=search_query) |
                Q(email__icontains=search_query)
            ).exclude(id=request.user.id)

            users_data = []
            for user in users:
                # 检查是否已关注 - 统一使用 UserFollow
                is_following = UserFollow.objects.filter(
                    follower=request.user,
                    following=user
                ).exists()

                # 检查是否在黑名单中
                is_blocked = UserBlacklist.objects.filter(
                    user=request.user,
                    blocked_user=user
                ).exists()

                users_data.append({
                    'id': user.id,
                    'username': user.username,
                    'avatar': user.avatar.url if user.avatar else '/media/avatars/default-avatar.png',
                    'email': user.email,
                    'bio': user.bio or '这个用户很懒，还没有写个人简介...',
                    'interests': user.interests,
                    'registration_date': user.date_joined.strftime('%Y-%m-%d'),
                    'is_following': is_following,
                    'is_blocked': is_blocked
                })

            return JsonResponse({
                'success': True,
                'users': users_data
            })

        except Exception as e:
            return JsonResponse({'success': False, 'message': f'搜索失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})



@require_POST
@csrf_exempt
def toggle_follow(request):
    """关注/取消关注用户"""
    print(f"toggle_follow 被调用，用户: {request.user.username}")

    if not request.user.is_authenticated:
        return JsonResponse({'success': False, 'message': '请先登录'})

    try:
        if request.content_type == 'application/json':
            data = json.loads(request.body)
            user_id = data.get('user_id')
        else:
            user_id = request.POST.get('user_id')

        if not user_id:
            return JsonResponse({'success': False, 'message': '用户ID不能为空'})

        target_user = User.objects.get(id=user_id)

        if request.user == target_user:
            return JsonResponse({'success': False, 'message': '不能关注自己'})

        # 检查是否已关注
        follow_relationship = UserFollow.objects.filter(
            follower=request.user,
            following=target_user
        ).first()

        if follow_relationship:
            # 取消关注
            follow_relationship.delete()
            action = 'unfollowed'
            message = f'已取消关注 {target_user.username}'
            print(f"取消关注: {request.user.username} -> {target_user.username}")
        else:
            # 关注
            UserFollow.objects.create(
                follower=request.user,
                following=target_user
            )
            action = 'followed'
            message = f'已关注 {target_user.username}'
            print(f"关注: {request.user.username} -> {target_user.username}")

        # 获取最新的统计信息 - 修复：移到条件分支之外
        following_count = UserFollow.objects.filter(follower=request.user).count()
        followers_count = UserFollow.objects.filter(following=request.user).count()

        stats = {
            'following_count': following_count,
            'followers_count': followers_count,
        }

        print(f"统计信息: 关注 {following_count}, 粉丝 {followers_count}")

        return JsonResponse({
            'success': True,
            'action': action,
            'message': message,
            'target_username': target_user.username,
            'stats': stats
        })

    except User.DoesNotExist:
        print(f"用户不存在: {user_id}")
        return JsonResponse({'success': False, 'message': '用户不存在'})
    except Exception as e:
        print(f"toggle_follow 异常: {str(e)}")
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


def get_follow_data(request):
    """获取关注和粉丝数据"""
    if not request.user.is_authenticated:
        return JsonResponse({'success': False, 'message': '请先登录'})

    # 获取我关注的人
    following = UserFollow.objects.filter(follower=request.user).select_related('following')
    following_data = []
    for follow in following:
        following_data.append({
            'id': follow.following.id,
            'username': follow.following.username,
            'avatar': follow.following.avatar.url if follow.following.avatar else '/media/avatars/default-avatar.png',
            'bio': follow.following.bio or '这个用户很懒，还没有写个人简介...',
            'registration_date': follow.following.date_joined.strftime('%Y-%m-%d'),
            'created_at': follow.created_at.strftime('%Y-%m-%d %H:%M')
        })

    # 获取我的粉丝
    followers = UserFollow.objects.filter(following=request.user).select_related('follower')
    followers_data = []
    for follow in followers:
        # 检查是否互相关注
        is_following_back = UserFollow.objects.filter(
            follower=request.user,
            following=follow.follower
        ).exists()

        followers_data.append({
            'id': follow.follower.id,
            'username': follow.follower.username,
            'avatar': follow.follower.avatar.url if follow.follower.avatar else '/media/avatars/default-avatar.png',
            'bio': follow.follower.bio or '这个用户很懒，还没有写个人简介...',
            'registration_date': follow.follower.date_joined.strftime('%Y-%m-%d'),
            'created_at': follow.created_at.strftime('%Y-%m-%d %H:%M'),
            'is_following_back': is_following_back
        })

    return JsonResponse({
        'success': True,
        'following': following_data,
        'followers': followers_data
    })

# 获取用户详情
def get_user_info(request):
    """获取用户详细信息"""
    try:
        user_id = request.GET.get('user_id')
        user = get_object_or_404(User, id=user_id)

        # 获取用户头像URL
        if user.avatar:
            avatar_url = user.avatar.url
        else:
            avatar_url = '/static/images/default-avatar.png'

        user_data = {
            'id': user.id,
            'username': user.username,
            'bio': user.bio or '这个用户很懒，还没有写个人简介...',
            'avatar': avatar_url,
            'email': user.email or '未设置邮箱',
            'registration_date': user.date_joined.strftime('%Y年%m月%d日'),
            'interests': user.interests if user.interests else []
        }

        return JsonResponse({'success': True, 'user': user_data})

    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


# 新增函数：拉黑/取消拉黑用户
@login_required
@csrf_exempt
def toggle_block(request):
    """拉黑或取消拉黑用户"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST
            target_user_id = data.get('user_id')

            if not target_user_id:
                return JsonResponse({'success': False, 'message': '用户ID不能为空'})

            target_user = User.objects.get(id=target_user_id)

            # 检查是否已拉黑
            blacklist_entry = UserBlacklist.objects.filter(
                user=request.user,
                blocked_user=target_user
            ).first()

            if blacklist_entry:
                # 取消拉黑
                blacklist_entry.delete()
                return JsonResponse({
                    'success': True,
                    'action': 'unblock',
                    'message': f'已取消拉黑 {target_user.username}'
                })
            else:
                # 拉黑
                UserBlacklist.objects.create(
                    user=request.user,
                    blocked_user=target_user
                )
                return JsonResponse({
                    'success': True,
                    'action': 'block',
                    'message': f'已拉黑 {target_user.username}'
                })

        except User.DoesNotExist:
            return JsonResponse({'success': False, 'message': '用户不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


# 新增函数：清除通知
@login_required
@csrf_exempt
def clear_notifications(request):
    """清除消息通知"""
    if request.method == 'POST':
        try:
            notification_type = request.POST.get('type', 'all')

            if notification_type == 'messages' or notification_type == 'all':
                # 标记所有未读消息为已读
                PrivateMessage.objects.filter(
                    receiver=request.user,
                    is_read=False
                ).update(is_read=True)

            return JsonResponse({
                'success': True,
                'message': '通知已清除'
            })

        except Exception as e:
            return JsonResponse({'success': False, 'message': f'清除失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@staff_member_required
@require_http_methods(["POST"])
def add_category(request):
    """添加分类"""
    try:
        name = request.POST.get('name', '').strip()
        description = request.POST.get('description', '').strip()
        icon = request.POST.get('icon', '').strip()
        is_active = request.POST.get('is_active') == 'true'

        if not name:
            return JsonResponse({'success': False, 'message': '分类名称不能为空'})

        # 检查分类名称是否已存在
        if ActivityCategory.objects.filter(name=name).exists():
            return JsonResponse({'success': False, 'message': '分类名称已存在'})

        # 创建分类
        category = ActivityCategory.objects.create(
            name=name,
            description=description,
            icon=icon,
            is_active=is_active
        )

        return JsonResponse({'success': True, 'message': f'分类 "{name}" 添加成功'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'添加失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def edit_category(request, category_id):
    """编辑分类"""
    try:
        category = ActivityCategory.objects.get(id=category_id)
        name = request.POST.get('name', '').strip()
        description = request.POST.get('description', '').strip()
        icon = request.POST.get('icon', '').strip()
        is_active = request.POST.get('is_active') == 'true'

        if not name:
            return JsonResponse({'success': False, 'message': '分类名称不能为空'})

        # 检查分类名称是否与其他分类重复
        if ActivityCategory.objects.filter(name=name).exclude(id=category_id).exists():
            return JsonResponse({'success': False, 'message': '分类名称已存在'})

        # 更新分类
        category.name = name
        category.description = description
        category.icon = icon
        category.is_active = is_active
        category.save()

        return JsonResponse({'success': True, 'message': f'分类 "{name}" 更新成功'})
    except ActivityCategory.DoesNotExist:
        return JsonResponse({'success': False, 'message': '分类不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'更新失败: {str(e)}'})


@staff_member_required
@require_http_methods(["POST"])
def delete_category(request, category_id):
    """删除分类"""
    try:
        category = ActivityCategory.objects.get(id=category_id)
        category_name = category.name

        # 检查分类下是否有活动
        if category.activity_set.exists():
            return JsonResponse({'success': False, 'message': '该分类下有活动，无法删除'})

        # 删除分类
        category.delete()

        return JsonResponse({'success': True, 'message': f'分类 "{category_name}" 删除成功'})
    except ActivityCategory.DoesNotExist:
        return JsonResponse({'success': False, 'message': '分类不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'删除失败: {str(e)}'})


@login_required
@csrf_exempt
def get_group_info(request):
    """获取群组信息"""
    if request.method == 'GET':
        try:
            group_id = request.GET.get('group_id')
            if not group_id:
                return JsonResponse({'success': False, 'message': '缺少群组ID'})

            group = ChatGroup.objects.get(id=group_id)

            # 检查用户是否在群组中
            if not GroupMembership.objects.filter(group=group, user=request.user).exists():
                return JsonResponse({'success': False, 'message': '您不在该群组中'})

            # 获取群组成员
            members = GroupMembership.objects.filter(group=group).select_related('user')
            members_data = []
            for membership in members:
                members_data.append({
                    'id': membership.user.id,
                    'username': membership.user.username,
                    'avatar': membership.user.avatar.url if membership.user.avatar else '/media/avatars/default-avatar.png',
                    'role': membership.role,
                    'is_online': False  # 可以添加在线状态功能
                })

            # 获取群组统计信息
            member_count = group.members.count()
            message_count = GroupMessage.objects.filter(group=group).count()

            return JsonResponse({
                'success': True,
                'group': {
                    'id': group.id,
                    'name': group.name,
                    'description': group.description,
                    'avatar': group.avatar.url if group.avatar else '/media/group_avatars/default-avatar.png',
                    'creator_id': group.creator.id,
                    'creator_name': group.creator.username,
                    'member_count': member_count,
                    'message_count': message_count,
                    'max_members': group.max_members,
                    'created_at': group.created_at.strftime('%Y-%m-%d %H:%M'),
                    'is_creator': group.creator == request.user,
                    'members': members_data
                }
            })

        except ChatGroup.DoesNotExist:
            return JsonResponse({'success': False, 'message': '群组不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'获取群组信息失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@login_required
@csrf_exempt
def leave_group(request):
    """退出群组"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST
            group_id = data.get('group_id')

            if not group_id:
                return JsonResponse({'success': False, 'message': '缺少群组ID'})

            group = ChatGroup.objects.get(id=group_id)
            membership = GroupMembership.objects.get(group=group, user=request.user)

            # 检查是否是群主
            if membership.role == 'owner':
                # 群主退出需要先转让群主权限或解散群组
                # 检查是否还有其他成员
                other_members = GroupMembership.objects.filter(group=group).exclude(user=request.user)
                if other_members.exists():
                    return JsonResponse({
                        'success': False,
                        'message': '群主不能直接退出群组，请先转让群主权限或解散群组'
                    })
                else:
                    # 如果没有其他成员，直接删除群组
                    group.delete()
                    return JsonResponse({'success': True, 'message': '群组已解散'})

            # 普通成员直接退出
            membership.delete()

            # 更新群组最后活动时间
            group.updated_at = timezone.now()
            group.save()

            return JsonResponse({'success': True, 'message': '已成功退出群组'})

        except (ChatGroup.DoesNotExist, GroupMembership.DoesNotExist):
            return JsonResponse({'success': False, 'message': '群组或成员关系不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'退出群组失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@login_required
@csrf_exempt
def update_group_info(request):
    """更新群组信息"""
    if request.method == 'POST':
        try:
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST
            group_id = data.get('group_id')
            name = data.get('name', '').strip()
            description = data.get('description', '').strip()

            group = ChatGroup.objects.get(id=group_id)
            membership = GroupMembership.objects.get(group=group, user=request.user)

            # 检查权限
            if membership.role not in ['owner', 'admin']:
                return JsonResponse({'success': False, 'message': '没有权限修改群组信息'})

            if name:
                group.name = name
            if description:
                group.description = description

            group.save()

            return JsonResponse({'success': True, 'message': '群组信息更新成功'})

        except ChatGroup.DoesNotExist:
            return JsonResponse({'success': False, 'message': '群组不存在'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'更新群组信息失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})


@login_required
@csrf_exempt
def clear_chat_history(request):
    """清除聊天记录"""
    if request.method == 'POST':
        try:
            user = request.user
            data = json.loads(request.body) if request.content_type == 'application/json' else request.POST

            chat_type = data.get('type', 'private')
            target_id = data.get('target_id')

            if not target_id:
                return JsonResponse({'success': False, 'message': '缺少目标ID'})

            if chat_type == 'private':
                # 私聊：标记相关消息为已删除
                try:
                    other_user = User.objects.get(id=target_id)

                    # 更新用户接收的消息
                    PrivateMessage.objects.filter(
                        receiver=user,
                        sender=other_user
                    ).update(is_read=True)  # 标记为已读作为软删除

                    return JsonResponse({
                        'success': True,
                        'message': '私聊记录已清除'
                    })

                except User.DoesNotExist:
                    return JsonResponse({'success': False, 'message': '用户不存在'})

            elif chat_type == 'group':
                # 群聊：标记所有消息为已读
                try:
                    group = ChatGroup.objects.get(id=target_id)

                    # 检查用户是否在群组中
                    if not group.members.filter(id=user.id).exists():
                        return JsonResponse({'success': False, 'message': '您不在该群组中'})

                    # 获取用户未读的群消息并标记为已读
                    unread_messages = GroupMessage.objects.filter(
                        group=group
                    ).exclude(
                        id__in=MessageReadStatus.objects.filter(user=user).values('message_id')
                    )

                    for msg in unread_messages:
                        MessageReadStatus.objects.get_or_create(message=msg, user=user)

                    return JsonResponse({
                        'success': True,
                        'message': '群聊记录已清除'
                    })

                except ChatGroup.DoesNotExist:
                    return JsonResponse({'success': False, 'message': '群组不存在'})

            else:
                return JsonResponse({'success': False, 'message': '不支持的聊天类型'})

        except Exception as e:
            return JsonResponse({'success': False, 'message': f'清除失败: {str(e)}'})

    return JsonResponse({'success': False, 'message': '请求方法错误'})

# 积分
from django.db import transaction, models
from django.db.models import Count


# 在现有的 add_points 函数基础上完善
# 在现有的积分函数基础上完善
def add_points(user, action, source_id='', description=''):
    """为用户添加积分 - 完善版本"""
    try:
        # 检查用户是否被封禁
        if hasattr(user, 'account_status') and user.account_status == 'banned':
            return False, "用户被封禁，无法获得积分"

        # 获取积分规则
        rule = PointsRule.objects.filter(action=action, is_active=True).first()
        if not rule:
            return False, "未找到对应的积分规则"

        # 检查每日上限
        if rule.daily_limit > 0:
            today = timezone.now().date()
            today_count = PointsHistory.objects.filter(
                user=user,
                source_type=action,
                created_at__date=today
            ).count()
            if today_count >= rule.daily_limit:
                return False, "今日该动作积分获取已达上限"

        # 使用事务确保数据一致性
        with transaction.atomic():
            # 更新用户积分
            user.points += rule.points
            # 如果用户模型有总积分字段，也更新它
            if hasattr(user, 'total_points_earned'):
                user.total_points_earned += rule.points
            user.save()

            # 记录积分历史
            PointsHistory.objects.create(
                user=user,
                points=rule.points,
                source_type=action,
                source_id=str(source_id),
                description=description or rule.name
            )

        return True, f"获得{rule.points}积分"

    except Exception as e:
        return False, f"添加积分失败: {str(e)}"

# 完善积分扣除函数
def deduct_points(user, points, source_type, source_id='', description=''):
    """扣除用户积分 - 完善版本"""
    try:
        if hasattr(user, 'account_status') and user.account_status == 'banned':
            return False, "用户被封禁，无法操作积分"

        if user.points < points:
            return False, "积分不足"

        # 使用事务确保数据一致性
        with transaction.atomic():
            # 更新用户积分
            user.points -= points
            user.save()

            # 记录积分历史
            PointsHistory.objects.create(
                user=user,
                points=-points,
                source_type=source_type,
                source_id=str(source_id),
                description=description
            )

        return True, f"扣除{points}积分成功"

    except Exception as e:
        return False, f"扣除积分失败: {str(e)}"

# 添加积分奖励的便捷函数
def award_points_for_activity_join(user, activity):
    """用户报名活动获得积分"""
    return add_points(
        user,
        'activity_join',
        activity.id,
        f'报名活动: {activity.title}'
    )

def award_points_for_activity_review(user, activity):
    """用户评价活动获得积分"""
    return add_points(
        user,
        'activity_review',
        activity.id,
        f'评价活动: {activity.title}'
    )

# 完善积分商城主页
def points_mall(request):
    """积分商城主页"""
    # 1. 初始化上下文变量（确保即使后续逻辑出错，也有基础上下文）
    context = {
        'products': [],
        'popular_products': [],
        'user_points': {'available_points': 0, 'total_points': 0},
        'today_signed': False,
        'consecutive_days': 0,
        'selected_category': '',
        'sort_by': 'popular'
    }

    try:
        # 2. 处理业务逻辑（分类、排序、用户信息等）
        category = request.GET.get('category', '')
        sort_by = request.GET.get('sort', 'popular')

        # 商品查询
        products = PointsProduct.objects.filter(status='active')
        if category:
            products = products.filter(category=category)

        # 排序逻辑
        if sort_by == 'points_asc':
            products = products.order_by('points_required')
        elif sort_by == 'points_desc':
            products = products.order_by('-points_required')
        elif sort_by == 'newest':
            products = products.order_by('-created_at')
        else:
            products = products.order_by('-exchange_count', 'points_required')

        # 热门商品
        popular_products = PointsProduct.objects.filter(
            status='active', stock__gt=0
        ).order_by('-exchange_count')[:6]

        # 用户积分和签到状态（仅登录用户）
        if request.user.is_authenticated:
            user_points = {
                'available_points': request.user.points,
                'total_points': getattr(request.user, 'total_points_earned', request.user.points)
            }
            today = timezone.now().date()
            today_signin = DailySignIn.objects.filter(user=request.user, signin_date=today).first()
            today_signed = bool(today_signin)
            consecutive_days = today_signin.consecutive_days if today_signin else 0

            # 更新上下文
            context.update({
                'products': products,
                'popular_products': popular_products,
                'user_points': user_points,
                'today_signed': today_signed,
                'consecutive_days': consecutive_days,
                'selected_category': category,
                'sort_by': sort_by
            })
        else:
            # 未登录用户仅展示商品，不展示积分
            context.update({
                'products': products,
                'popular_products': popular_products,
                'selected_category': category,
                'sort_by': sort_by
            })

    except Exception as e:
        # 3. 异常处理：即使出错，也返回响应（可添加错误日志）
        print(f"points_mall 视图错误: {str(e)}")
        # 保持上下文基础数据，避免模板渲染失败

    # 4. 兜底返回：确保函数末尾一定有 return
    return render(request, 'points_mall.html', context)


@login_required
@require_http_methods(["POST"])
@csrf_exempt
def daily_signin(request):
    """用户每日签到功能 - 修复版本"""
    try:
        # 添加调试信息
        print(f"签到请求来自用户: {request.user.username}")

        today = timezone.now().date()
        user = request.user

        # 检查是否已签到
        if DailySignIn.objects.filter(user=user, signin_date=today).exists():
            print("用户今天已签到")
            return JsonResponse({
                'success': False,
                'message': '您今天已经签过到了哦~'
            })

        # 计算连续签到天数
        yesterday = today - timedelta(days=1)
        yesterday_signin = DailySignIn.objects.filter(
            user=user,
            signin_date=yesterday
        ).first()

        consecutive_days = 1
        if yesterday_signin:
            consecutive_days = yesterday_signin.consecutive_days + 1

        # 获取签到积分规则
        signin_rule = PointsRule.objects.filter(
            action='daily_signin',
            is_active=True
        ).first()

        points_earned = signin_rule.points if signin_rule else 5

        # 连续签到奖励（每7天额外奖励）
        if consecutive_days % 7 == 0:
            points_earned += 5

        with transaction.atomic():
            # 创建签到记录
            signin_record = DailySignIn.objects.create(
                user=user,
                signin_date=today,
                consecutive_days=consecutive_days,
                points_earned=points_earned
            )

            # 更新用户积分
            user.points += points_earned
            user.save()

            # 记录积分历史
            PointsHistory.objects.create(
                user=user,
                points=points_earned,
                source_type='daily_signin',
                description=f'每日签到，连续{consecutive_days}天，获得{points_earned}积分'
            )

        print(f"签到成功: 用户 {user.username} 获得 {points_earned} 积分")
        return JsonResponse({
            'success': True,
            'message': f'签到成功！获得{points_earned}积分，已连续签到{consecutive_days}天',
            'consecutive_days': consecutive_days,
            'points_earned': points_earned
        })

    except Exception as e:
        print(f"签到错误: {str(e)}")
        import traceback
        print(f"详细错误: {traceback.format_exc()}")
        return JsonResponse({
            'success': False,
            'message': f'签到失败：{str(e)}'
        })


@login_required
@require_http_methods(["POST"])
@csrf_exempt
def exchange_product(request, product_id):
    """兑换商品 - 添加更多调试信息"""
    try:
        print(f"=== 兑换请求开始 ===")
        print(f"用户: {request.user.username}")
        print(f"商品ID: {product_id}")
        print(f"请求方法: {request.method}")
        print(f"内容类型: {request.content_type}")

        # 获取请求数据
        if request.content_type == 'application/json':
            data = json.loads(request.body)
        else:
            data = request.POST

        print(f"请求数据: {data}")

        product = get_object_or_404(PointsProduct, id=product_id, status='active')
        print(f"找到商品: {product.name}")

        # ... 其余兑换逻辑保持不变，但添加更多调试信息 ...

    except Exception as e:
        print(f"兑换过程发生错误: {str(e)}")
        import traceback
        print(f"错误详情: {traceback.format_exc()}")
        return JsonResponse({
            'success': False,
            'message': f'兑换失败: {str(e)}'
        })


# 完善积分历史页面
@login_required
def points_history(request):
    """积分历史记录 - 完善版本"""
    history_records = PointsHistory.objects.filter(user=request.user).order_by('-created_at')

    # 统计信息
    total_earned = PointsHistory.objects.filter(
        user=request.user,
        points__gt=0
    ).aggregate(total=Sum('points'))['total'] or 0

    total_used = abs(PointsHistory.objects.filter(
        user=request.user,
        points__lt=0
    ).aggregate(total=Sum('points'))['total'] or 0)

    # 分页
    paginator = Paginator(history_records, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    context = {
        'page_obj': page_obj,
        'user_points': {
            'total_points': total_earned,
            'available_points': request.user.points,
            'total_used': total_used
        }
    }

    return render(request, 'points_history.html', context)

# 完善我的兑换记录页面
@login_required
def my_exchanges(request):
    """我的兑换记录 - 修复版本"""
    try:
        print(f"开始获取用户 {request.user.username} 的兑换记录")  # 调试信息

        # 使用正确的查询获取兑换记录
        exchanges = PointsExchange.objects.filter(
            user=request.user
        ).select_related('product').order_by('-created_at')

        print(f"找到 {exchanges.count()} 条兑换记录")  # 调试信息

        # 分页
        paginator = Paginator(exchanges, 10)
        page_number = request.GET.get('page')
        page_obj = paginator.get_page(page_number)

        context = {
            'page_obj': page_obj,
        }

        return render(request, 'my_exchanges.html', context)

    except Exception as e:
        print(f"获取兑换记录错误: {str(e)}")
        # 出错时返回空数据但确保页面能正常显示
        context = {
            'page_obj': [],
        }
        return render(request, 'my_exchanges.html', context)



# 完善商品兑换功能
# 在 views.py 中修复 exchange_product 函数
@login_required
@require_http_methods(["POST"])
@csrf_exempt
def exchange_product(request, product_id):
    """兑换商品 - 添加详细调试信息"""
    try:
        print(f"=== 开始兑换流程 ===")
        print(f"用户: {request.user.username} (ID: {request.user.id})")
        print(f"商品ID: {product_id}")

        product = get_object_or_404(PointsProduct, id=product_id, status='active')
        print(f"商品信息: {product.name}, 库存: {product.stock}, 所需积分: {product.points_required}")
        print(f"用户当前积分: {request.user.points}")

        # 检查积分是否足够
        if request.user.points < product.points_required:
            print("积分不足，兑换失败")
            return JsonResponse({
                'success': False,
                'message': f'积分不足，需要{product.points_required}积分，您当前有{request.user.points}积分'
            })

        # 检查库存
        if product.stock <= 0:
            print("商品库存不足")
            return JsonResponse({
                'success': False,
                'message': '商品已售罄'
            })

        # 获取收货信息
        shipping_address = ''
        contact_name = ''
        contact_phone = ''

        if request.content_type == 'application/json':
            data = json.loads(request.body)
            shipping_address = data.get('shipping_address', '').strip()
            contact_name = data.get('contact_name', '').strip()
            contact_phone = data.get('contact_phone', '').strip()
        else:
            shipping_address = request.POST.get('shipping_address', '').strip()
            contact_name = request.POST.get('contact_name', '').strip()
            contact_phone = request.POST.get('contact_phone', '').strip()

        print(f"收货信息 - 地址: {shipping_address}, 联系人: {contact_name}, 电话: {contact_phone}")

        # 实物商品需要收货信息
        if product.category == 'physical':
            if not all([shipping_address, contact_name, contact_phone]):
                print("实物商品收货信息不完整")
                return JsonResponse({
                    'success': False,
                    'message': '请填写完整的收货信息'
                })

        # 使用事务确保数据一致性
        with transaction.atomic():
            # 扣除用户积分
            request.user.points -= product.points_required
            request.user.save()
            print(f"扣除积分成功，用户剩余积分: {request.user.points}")

            # 记录积分历史
            points_history = PointsHistory.objects.create(
                user=request.user,
                points=-product.points_required,
                source_type='points_exchange',
                source_id=str(product.id),
                description=f'兑换商品: {product.name}'
            )
            print(f"积分历史记录创建成功 - ID: {points_history.id}")

            # 减少商品库存
            product.stock -= 1
            product.exchange_count += 1
            product.save()
            print(f"商品库存更新 - 新库存: {product.stock}, 兑换次数: {product.exchange_count}")

            # 创建兑换记录
            exchange = PointsExchange.objects.create(
                user=request.user,
                product=product,
                points_used=product.points_required,
                shipping_address=shipping_address,
                contact_name=contact_name,
                contact_phone=contact_phone,
                status='pending'
            )
            print(f"兑换记录创建成功 - ID: {exchange.id}")

            # 为虚拟商品生成兑换码
            if product.category == 'virtual':
                exchange.exchange_code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=12))
                exchange.save()
                print(f"虚拟商品兑换码生成: {exchange.exchange_code}")

        # 验证记录是否创建成功
        exchange_count = PointsExchange.objects.filter(user=request.user).count()
        print(f"用户总兑换记录数: {exchange_count}")

        return JsonResponse({
            'success': True,
            'message': '兑换成功！' + (
                '我们将在3个工作日内处理您的订单' if product.category == 'physical' else '请查看兑换码'),
            'exchange_id': exchange.id,
            'is_virtual': product.category == 'virtual',
            'exchange_code': exchange.exchange_code if product.category == 'virtual' else '',
            'new_points': request.user.points,
            'debug': {
                'exchange_count': exchange_count,
                'product_stock': product.stock
            }
        })

    except Exception as e:
        print(f"兑换过程发生错误: {str(e)}")
        import traceback
        print(f"错误详情: {traceback.format_exc()}")
        return JsonResponse({
            'success': False,
            'message': f'兑换失败: {str(e)}'
        })
# 完善积分规则页面
def points_rules(request):
    """积分规则页面"""
    rules = PointsRule.objects.filter(is_active=True).order_by('points')

    context = {
        'rules': rules
    }

    return render(request, 'points_rules.html', context)


def get_user_points_info(user):
    """获取用户积分信息"""
    if user.is_authenticated:
        total_earned = PointsHistory.objects.filter(
            user=user,
            points__gt=0
        ).aggregate(total=Sum('points'))['total'] or 0

        return {
            'available_points': user.points,
            'total_points': total_earned
        }
    return {'available_points': 0, 'total_points': 0}


@login_required
def debug_exchanges(request):
    """调试兑换数据"""
    user = request.user

    # 检查用户的所有兑换记录
    exchanges = PointsExchange.objects.filter(user=user)
    exchange_data = list(exchanges.values('id', 'product__name', 'points_used', 'status', 'created_at'))

    # 检查积分历史
    points_history = PointsHistory.objects.filter(
        user=user,
        source_type='points_exchange'
    )
    points_data = list(points_history.values('id', 'points', 'description', 'created_at'))

    debug_info = {
        'user': {
            'id': user.id,
            'username': user.username,
            'points': user.points
        },
        'exchanges_count': exchanges.count(),
        'exchanges': exchange_data,
        'points_history_count': points_history.count(),
        'points_history': points_data
    }

    return JsonResponse(debug_info)


# 管理员积分
@staff_member_required
def admin_dashboard(request):
    """管理员后台主页 - 增强版，包含积分管理"""
    current_tab = request.GET.get('tab', 'dashboard')

    # 获取今日数据
    today = timezone.now().date()

    # 基础统计
    today_activities = Activity.objects.filter(
        created_at__date=today,
        status='published'
    ).count()

    today_users = User.objects.filter(date_joined__date=today).count()
    total_activities = Activity.objects.count()
    total_users = User.objects.count()
    total_participations = ActivityParticipation.objects.count()

    # 热门活动
    popular_activities = Activity.objects.filter(
        status='published'
    ).select_related('category', 'organizer').order_by('-current_participants')[:5]

    # 活动状态统计
    activity_status_stats = Activity.objects.values('status').annotate(count=Count('id'))

    # 活跃用户（组织活动最多的用户）
    active_users = User.objects.annotate(
        activity_count=Count('organized_activities')
    ).filter(activity_count__gt=0).order_by('-activity_count')[:5]

    # 积分相关统计
    total_points_distributed = PointsHistory.objects.filter(points__gt=0).aggregate(
        total=Sum('points')
    )['total'] or 0

    total_points_used = PointsHistory.objects.filter(points__lt=0).aggregate(
        total=Sum('points')
    )['total'] or 0

    points_products_count = PointsProduct.objects.count()
    active_points_products = PointsProduct.objects.filter(status='active').count()

    # 今日积分数据
    today_points = PointsHistory.objects.filter(
        created_at__date=today
    ).aggregate(
        earned=Sum('points', filter=Q(points__gt=0)),
        used=Sum('points', filter=Q(points__lt=0))
    )

    context = {
        'current_tab': current_tab,
        'today_activities': today_activities,
        'today_users': today_users,
        'total_activities': total_activities,
        'total_users': total_users,
        'total_participations': total_participations,
        'popular_activities': popular_activities,
        'activity_status_stats': activity_status_stats,
        'active_users': active_users,
        'categories': ActivityCategory.objects.filter(is_active=True),

        # 积分相关数据
        'total_points_distributed': total_points_distributed,
        'total_points_used': abs(total_points_used),
        'points_products_count': points_products_count,
        'active_points_products': active_points_products,
        'today_points_earned': today_points['earned'] or 0,
        'today_points_used': abs(today_points['used'] or 0),
    }

    return render(request, 'admin_index.html', context)


# 积分管理相关视图
@staff_member_required
def points_management(request):
    """积分管理主页面"""
    current_tab = 'points'

    # 获取搜索和筛选参数
    search_query = request.GET.get('search', '')
    product_status = request.GET.get('status', '')
    product_category = request.GET.get('category', '')

    # 积分商品查询
    products = PointsProduct.objects.all()

    if search_query:
        products = products.filter(
            Q(name__icontains=search_query) |
            Q(description__icontains=search_query)
        )

    if product_status:
        products = products.filter(status=product_status)

    if product_category:
        products = products.filter(category=product_category)

    # 分页
    paginator = Paginator(products, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    # 积分统计
    points_stats = {
        'total_products': PointsProduct.objects.count(),
        'active_products': PointsProduct.objects.filter(status='active').count(),
        'total_exchanges': PointsExchange.objects.count(),
        'pending_exchanges': PointsExchange.objects.filter(status='pending').count(),
    }

    context = {
        'current_tab': current_tab,
        'page_obj': page_obj,
        'points_stats': points_stats,
        'search_query': search_query,
        'product_status': product_status,
        'product_category': product_category,
        'status_choices': PointsProduct.STATUS_CHOICES,
        'category_choices': PointsProduct.CATEGORY_CHOICES,
    }

    return render(request, 'admin_points.html', context)


@staff_member_required
def admin_points_history(request):
    """管理员积分历史记录"""
    current_tab = 'points_history'

    # 获取筛选参数
    source_type = request.GET.get('source_type', '')
    user_id = request.GET.get('user_id', '')
    date_range = request.GET.get('date_range', '')

    # 积分历史查询
    points_history = PointsHistory.objects.select_related('user').all()

    if source_type:
        points_history = points_history.filter(source_type=source_type)

    if user_id:
        points_history = points_history.filter(user_id=user_id)

    if date_range:
        today = timezone.now().date()
        if date_range == 'today':
            points_history = points_history.filter(created_at__date=today)
        elif date_range == 'week':
            week_ago = today - timezone.timedelta(days=7)
            points_history = points_history.filter(created_at__date__gte=week_ago)
        elif date_range == 'month':
            month_ago = today - timezone.timedelta(days=30)
            points_history = points_history.filter(created_at__date__gte=month_ago)

    # 分页
    paginator = Paginator(points_history.order_by('-created_at'), 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    # 统计
    total_earned = points_history.filter(points__gt=0).aggregate(
        total=Sum('points')
    )['total'] or 0

    total_used = points_history.filter(points__lt=0).aggregate(
        total=Sum('points')
    )['total'] or 0

    context = {
        'current_tab': current_tab,
        'page_obj': page_obj,
        'source_type': source_type,
        'user_id': user_id,
        'date_range': date_range,
        'source_choices': PointsHistory.POINTS_SOURCE_CHOICES,
        'total_earned': total_earned,
        'total_used': abs(total_used),
        'net_points': total_earned + total_used,  # total_used 是负数
    }

    return render(request, 'admin_points_history.html', context)


@staff_member_required
def points_exchanges(request):
    """积分兑换记录管理"""
    current_tab = 'points_exchanges'

    # 获取筛选参数
    status_filter = request.GET.get('status', '')
    product_id = request.GET.get('product_id', '')

    # 兑换记录查询
    exchanges = PointsExchange.objects.select_related('user', 'product').all()

    if status_filter:
        exchanges = exchanges.filter(status=status_filter)

    if product_id:
        exchanges = exchanges.filter(product_id=product_id)

    # 分页
    paginator = Paginator(exchanges.order_by('-created_at'), 15)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    # 统计
    exchange_stats = {
        'total': PointsExchange.objects.count(),
        'pending': PointsExchange.objects.filter(status='pending').count(),
        'completed': PointsExchange.objects.filter(status='completed').count(),
        'cancelled': PointsExchange.objects.filter(status='cancelled').count(),
    }

    context = {
        'current_tab': current_tab,
        'page_obj': page_obj,
        'status_filter': status_filter,
        'product_id': product_id,
        'exchange_stats': exchange_stats,
        'status_choices': PointsExchange.STATUS_CHOICES,
        'products': PointsProduct.objects.all(),
    }

    return render(request, 'admin_points_exchanges.html', context)


@require_POST
@staff_member_required
def update_exchange_status(request, exchange_id):
    """更新兑换记录状态"""
    try:
        exchange = get_object_or_404(PointsExchange, id=exchange_id)
        new_status = request.POST.get('status')
        tracking_number = request.POST.get('tracking_number', '')

        if new_status not in dict(PointsExchange.STATUS_CHOICES):
            return JsonResponse({'success': False, 'message': '无效的状态'})

        exchange.status = new_status

        if new_status == 'shipped' and tracking_number:
            exchange.tracking_number = tracking_number

        exchange.save()

        return JsonResponse({
            'success': True,
            'message': '状态更新成功',
            'new_status': exchange.get_status_display()
        })

    except Exception as e:
        return JsonResponse({'success': False, 'message': f'更新失败: {str(e)}'})


@require_POST
@staff_member_required
def add_points_product(request):
    """添加积分商品"""
    try:
        name = request.POST.get('name', '').strip()
        description = request.POST.get('description', '').strip()
        category = request.POST.get('category', 'physical')
        points_required = int(request.POST.get('points_required', 0))
        stock = int(request.POST.get('stock', 0))
        original_price = request.POST.get('original_price')
        status = request.POST.get('status', 'active')

        if not name or points_required <= 0:
            return JsonResponse({'success': False, 'message': '请填写完整的商品信息'})

        product = PointsProduct.objects.create(
            name=name,
            description=description,
            category=category,
            points_required=points_required,
            stock=stock,
            original_price=original_price if original_price else None,
            status=status
        )

        # 处理图片上传
        if 'image' in request.FILES:
            product.image = request.FILES['image']
            product.save()

        return JsonResponse({
            'success': True,
            'message': '商品添加成功',
            'product_id': product.id
        })

    except Exception as e:
        return JsonResponse({'success': False, 'message': f'添加失败: {str(e)}'})


@require_POST
@staff_member_required
def update_points_product(request, product_id):
    """更新积分商品"""
    try:
        product = get_object_or_404(PointsProduct, id=product_id)

        product.name = request.POST.get('name', product.name).strip()
        product.description = request.POST.get('description', product.description).strip()
        product.category = request.POST.get('category', product.category)
        product.points_required = int(request.POST.get('points_required', product.points_required))
        product.stock = int(request.POST.get('stock', product.stock))
        product.status = request.POST.get('status', product.status)

        original_price = request.POST.get('original_price')
        product.original_price = original_price if original_price else None

        # 处理图片上传
        if 'image' in request.FILES:
            product.image = request.FILES['image']

        product.save()

        return JsonResponse({
            'success': True,
            'message': '商品更新成功'
        })

    except Exception as e:
        return JsonResponse({'success': False, 'message': f'更新失败: {str(e)}'})


@require_POST
@staff_member_required
def delete_points_product(request, product_id):
    """删除积分商品"""
    try:
        product = get_object_or_404(PointsProduct, id=product_id)

        # 检查是否有兑换记录
        if product.exchanges.exists():
            return JsonResponse({
                'success': False,
                'message': '该商品已有兑换记录，无法删除'
            })

        product.delete()

        return JsonResponse({
            'success': True,
            'message': '商品删除成功'
        })

    except Exception as e:
        return JsonResponse({'success': False, 'message': f'删除失败: {str(e)}'})


@login_required
@csrf_exempt
def get_chat_history(request):
    """获取聊天历史记录"""
    try:
        chat_type = request.GET.get('type', 'private')
        target_id = request.GET.get('target_id')
        limit = int(request.GET.get('limit', 50))

        if not target_id:
            return JsonResponse({'success': False, 'message': '缺少目标ID'})

        messages_data = []

        if chat_type == 'private':
            # 获取私聊历史
            other_user = User.objects.get(id=target_id)
            messages = PrivateMessage.objects.filter(
                Q(sender=request.user, receiver=other_user) |
                Q(sender=other_user, receiver=request.user)
            ).select_related('sender', 'receiver').order_by('created_at')[:limit]

            for msg in messages:
                messages_data.append({
                    'type': 'private_message',
                    'message_id': msg.id,
                    'sender_id': msg.sender.id,
                    'sender_name': msg.sender.username,
                    'sender_avatar': get_avatar_url(msg.sender),
                    'content': msg.content,
                    'created_at': msg.created_at.isoformat(),
                    'is_own': msg.sender == request.user,
                    'is_read': msg.is_read
                })

        elif chat_type == 'group':
            # 获取群聊历史
            group = ChatGroup.objects.get(id=target_id)
            messages = GroupMessage.objects.filter(
                group=group
            ).select_related('sender', 'group').order_by('created_at')[:limit]

            for msg in messages:
                messages_data.append({
                    'type': 'group_message',
                    'message_id': msg.id,
                    'group_id': group.id,
                    'sender_id': msg.sender.id,
                    'sender_name': msg.sender.username,
                    'sender_avatar': get_avatar_url(msg.sender),
                    'content': msg.content,
                    'created_at': msg.created_at.isoformat(),
                    'is_own': msg.sender == request.user,
                    'message_type': msg.message_type
                })

        return JsonResponse({
            'success': True,
            'messages': messages_data
        })

    except Exception as e:
        logger.error(f"获取聊天历史失败: {str(e)}")
        return JsonResponse({'success': False, 'message': f'获取历史记录失败: {str(e)}'})


@csrf_exempt
def qq_login(request):
    """QQ登录 - 模拟模式（用于开发和测试）"""
    if request.method == 'GET':
        # 显示模拟QQ登录页面
        return render(request, 'qq_login_simulate.html')
    else:
        # 处理模拟登录
        return qq_login_simulate(request)


def qq_login_simulate(request):
    """模拟QQ登录处理"""
    if request.method == 'POST':
        try:
            # 模拟获取QQ用户信息
            simulated_qq_email = request.POST.get('simulated_email', '').strip()

            if not simulated_qq_email:
                return JsonResponse({
                    'success': False,
                    'message': '请输入模拟的QQ邮箱'
                })

            # 确保邮箱格式正确
            if not simulated_qq_email.endswith('@qq.com'):
                simulated_qq_email += '@qq.com'

            print(f"模拟QQ登录 - 邮箱: {simulated_qq_email}")

            # 检查邮箱是否已注册
            try:
                user = User.objects.get(email=simulated_qq_email)
                print(f"找到已注册用户: {user.username}")

                # 自动登录
                auth_login(request, user)

                return JsonResponse({
                    'success': True,
                    'message': '登录成功',
                    'redirect_url': '/meet/index/'
                })

            except User.DoesNotExist:
                print("用户未注册，需要跳转到注册页面")
                # 生成随机昵称
                random_nickname = f'QQ用户{random.randint(1000, 9999)}'

                return JsonResponse({
                    'success': False,
                    'need_register': True,
                    'message': '该QQ邮箱尚未注册，将跳转到注册页面',
                    'email': simulated_qq_email,
                    'nickname': random_nickname
                })

        except Exception as e:
            print(f"模拟QQ登录处理异常: {str(e)}")
            return JsonResponse({
                'success': False,
                'message': f'登录处理失败: {str(e)}'
            })

    return JsonResponse({
        'success': False,
        'message': '请求方法错误'
    })


def qq_callback(request):
    """处理QQ登录回调"""
    try:
        code = request.GET.get('code')
        if not code:
            return render(request, 'login.html', {'error_message': '授权失败，未获取到code'})

        oauth_qq = OAuthQQ()
        # 获取access_token
        access_token = oauth_qq.get_access_token(code)
        if not access_token:
            return render(request, 'login.html', {'error_message': '获取access_token失败'})

        # 获取openid
        openid = oauth_qq.get_openid(access_token)
        if not openid:
            return render(request, 'login.html', {'error_message': '获取openid失败'})

        # 检查该QQ是否已绑定用户
        try:
            # 假设你在User模型中有qq_openid字段存储OpenID
            user = User.objects.get(qq_openid=openid)
            # 已绑定用户，直接登录
            login(request, user)
            return redirect('/meet/index/')

        except User.DoesNotExist:
            # 未绑定用户，尝试获取QQ用户信息，并引导绑定或注册
            qq_user_info = oauth_qq.get_qq_user_info(access_token, openid)
            if qq_user_info:
                # 存储QQ用户信息和openid在session中，供后续绑定使用
                request.session['qq_openid'] = openid
                request.session['qq_user_info'] = qq_user_info
                # 跳转到绑定页面或注册页面，传递QQ用户信息
                return redirect(f'/user/register/?qq_nickname={qq_user_info.get("nickname", "")}')
            else:
                return render(request, 'login.html', {'error_message': '获取QQ用户信息失败'})

    except Exception as e:
        print(f"QQ登录回调处理异常: {str(e)}")
        return render(request, 'login.html', {'error_message': 'QQ登录处理异常，请重试'})


@staff_member_required
def admin_activity_detail(request, activity_id):
    """管理员活动审核详情页面"""
    try:
        activity = get_object_or_404(
            Activity.objects.select_related('category', 'organizer'),
            id=activity_id
        )

        context = {
            'activity': activity,
        }

        return render(request, 'admin_activity_detail.html', context)

    except Exception as e:
        messages.error(request, f'获取活动详情失败: {str(e)}')
        return redirect('admin_dashboard')


def get_online_users(request):
    return None

# views.py
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from .models import PrivateMessage, GroupMessage, ChatGroup

@login_required
def get_private_chat_history(request):
    """获取私聊历史消息"""
    target_id = request.GET.get('target_id')
    limit = int(request.GET.get('limit', 50))

    try:
        # 获取与目标用户的私聊消息
        messages = PrivateMessage.objects.filter(
            models.Q(sender=request.user, receiver_id=target_id) |
            models.Q(sender_id=target_id, receiver=request.user)
        ).select_related('sender', 'receiver').order_by('created_at')[:limit]

        message_list = []
        for msg in messages:
            message_list.append({
                'message_id': msg.id,
                'type': 'private_message',
                'sender_id': msg.sender.id,
                'sender_name': msg.sender.username,
                'sender_avatar': msg.sender.avatar.url if msg.sender.avatar else '/media/avatars/default-avatar.png',
                'content': msg.content,
                'created_at': msg.created_at.isoformat(),
                'is_own': msg.sender.id == request.user.id
            })

        return JsonResponse({
            'success': True,
            'messages': message_list
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': str(e)
        })

@login_required
def get_group_chat_history(request):
    """获取群聊历史消息"""
    group_id = request.GET.get('group_id')
    limit = int(request.GET.get('limit', 50))

    try:
        # 检查用户是否在群组中
        group = ChatGroup.objects.get(id=group_id)
        if not group.members.filter(id=request.user.id).exists():
            return JsonResponse({
                'success': False,
                'message': '您不在该群组中'
            })

        # 获取群组消息
        messages = GroupMessage.objects.filter(
            group_id=group_id
        ).select_related('sender', 'group').order_by('created_at')[:limit]

        message_list = []
        for msg in messages:
            message_list.append({
                'message_id': msg.id,
                'type': 'group_message',
                'group_id': group_id,
                'sender_id': msg.sender.id,
                'sender_name': msg.sender.username,
                'sender_avatar': msg.sender.avatar.url if msg.sender.avatar else '/media/avatars/default-avatar.png',
                'content': msg.content,
                'created_at': msg.created_at.isoformat(),
                'is_own': msg.sender.id == request.user.id
            })

        return JsonResponse({
            'success': True,
            'messages': message_list
        })

    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': str(e)
        })